home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows (5th Edition) / Programming Windows, 5th ed. - Companion CD (097-0002183)(1999).iso / Chap15 / ShowDib2 / Showdib2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-09  |  11.7 KB  |  347 lines

  1. /*----------------------------------------------
  2.    SHOWDIB2.C -- Shows a DIB in the client area
  3.                  (c) Charles Petzold, 1998
  4.   ----------------------------------------------*/
  5.  
  6. #include <windows.h>
  7. #include "dibfile.h"
  8. #include "resource.h"
  9.  
  10. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  11.  
  12. TCHAR szAppName[] = TEXT ("ShowDib2") ;
  13.  
  14. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  15.                     PSTR szCmdLine, int iCmdShow)
  16. {
  17.      HACCEL   hAccel ;
  18.      HWND     hwnd ;
  19.      MSG      msg ;
  20.      WNDCLASS wndclass ;
  21.  
  22.      wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  23.      wndclass.lpfnWndProc   = WndProc ;
  24.      wndclass.cbClsExtra    = 0 ;
  25.      wndclass.cbWndExtra    = 0 ;
  26.      wndclass.hInstance     = hInstance ;
  27.      wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  28.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  29.      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  30.      wndclass.lpszMenuName  = szAppName ;
  31.      wndclass.lpszClassName = szAppName ;
  32.  
  33.      if (!RegisterClass (&wndclass))
  34.      {
  35.           MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
  36.                       szAppName, MB_ICONERROR) ;
  37.           return 0 ;
  38.      }
  39.  
  40.      hwnd = CreateWindow (szAppName, TEXT ("Show DIB #2"),
  41.                           WS_OVERLAPPEDWINDOW,
  42.                           CW_USEDEFAULT, CW_USEDEFAULT,
  43.                           CW_USEDEFAULT, CW_USEDEFAULT, 
  44.                           NULL, NULL, hInstance, NULL) ;
  45.  
  46.      ShowWindow (hwnd, iCmdShow) ;
  47.      UpdateWindow (hwnd) ;
  48.  
  49.      hAccel = LoadAccelerators (hInstance, szAppName) ;
  50.  
  51.      while (GetMessage (&msg, NULL, 0, 0))
  52.      {
  53.           if (!TranslateAccelerator (hwnd, hAccel, &msg))
  54.           {
  55.                TranslateMessage (&msg) ;
  56.                DispatchMessage (&msg) ;
  57.           }
  58.      }
  59.      return msg.wParam ;
  60. }
  61.  
  62. int ShowDib (HDC hdc, BITMAPINFO * pbmi, BYTE * pBits, int cxDib, int cyDib, 
  63.              int cxClient, int cyClient, WORD wShow)
  64. {
  65.      switch (wShow)
  66.      {
  67.      case IDM_SHOW_NORMAL:
  68.           return SetDIBitsToDevice (hdc, 0, 0, cxDib, cyDib, 0, 0, 
  69.                                     0, cyDib, pBits, pbmi, DIB_RGB_COLORS) ;
  70.                
  71.      case IDM_SHOW_CENTER:
  72.           return SetDIBitsToDevice (hdc, (cxClient - cxDib) / 2,
  73.                                          (cyClient - cyDib) / 2, 
  74.                                     cxDib, cyDib, 0, 0, 
  75.                                     0, cyDib, pBits, pbmi, DIB_RGB_COLORS) ;
  76.  
  77.      case IDM_SHOW_STRETCH:
  78.           SetStretchBltMode (hdc, COLORONCOLOR) ;
  79.  
  80.           return StretchDIBits (hdc, 0, 0, cxClient, cyClient, 
  81.                                      0, 0, cxDib, cyDib,
  82.                                 pBits, pbmi, DIB_RGB_COLORS, SRCCOPY) ;
  83.  
  84.      case IDM_SHOW_ISOSTRETCH:
  85.           SetStretchBltMode (hdc, COLORONCOLOR) ;
  86.           SetMapMode (hdc, MM_ISOTROPIC) ;
  87.           SetWindowExtEx (hdc, cxDib, cyDib, NULL) ;
  88.           SetViewportExtEx (hdc, cxClient, cyClient, NULL) ;
  89.           SetWindowOrgEx (hdc, cxDib / 2, cyDib / 2, NULL) ;
  90.           SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ;
  91.  
  92.           return StretchDIBits (hdc, 0, 0, cxDib, cyDib, 
  93.                                      0, 0, cxDib, cyDib,
  94.                                 pBits, pbmi, DIB_RGB_COLORS, SRCCOPY) ;
  95.      }
  96.      return 0 ;
  97. }
  98.  
  99. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  100. {
  101.      static BITMAPFILEHEADER * pbmfh ;
  102.      static BITMAPINFO       * pbmi ;
  103.      static BYTE             * pBits ;
  104.      static DOCINFO            di = { sizeof (DOCINFO), 
  105.                                       TEXT ("ShowDib2: Printing") } ;
  106.      static int                cxClient, cyClient, cxDib, cyDib ;
  107.      static PRINTDLG           printdlg = { sizeof (PRINTDLG) } ;
  108.      static TCHAR              szFileName [MAX_PATH], szTitleName [MAX_PATH] ;
  109.      static WORD               wShow = IDM_SHOW_NORMAL ;
  110.      BOOL                      bSuccess ;
  111.      HDC                       hdc, hdcPrn ;
  112.      HGLOBAL                   hGlobal ;
  113.      HMENU                     hMenu ;
  114.      int                       cxPage, cyPage, iEnable ;
  115.      PAINTSTRUCT               ps ;
  116.      BYTE                    * pGlobal ;
  117.  
  118.      switch (message)
  119.      {
  120.      case WM_CREATE:
  121.           DibFileInitialize (hwnd) ;
  122.           return 0 ;
  123.  
  124.      case WM_SIZE:
  125.           cxClient = LOWORD (lParam) ;
  126.           cyClient = HIWORD (lParam) ;
  127.           return 0 ;
  128.  
  129.      case WM_INITMENUPOPUP:
  130.           hMenu = GetMenu (hwnd) ;
  131.  
  132.           if (pbmfh)
  133.                iEnable = MF_ENABLED ;
  134.           else
  135.                iEnable = MF_GRAYED ;
  136.  
  137.           EnableMenuItem (hMenu, IDM_FILE_SAVE,   iEnable) ;
  138.           EnableMenuItem (hMenu, IDM_FILE_PRINT,  iEnable) ;
  139.           EnableMenuItem (hMenu, IDM_EDIT_CUT,    iEnable) ;
  140.           EnableMenuItem (hMenu, IDM_EDIT_COPY,   iEnable) ;
  141.           EnableMenuItem (hMenu, IDM_EDIT_DELETE, iEnable) ;
  142.           return 0 ;
  143.  
  144.      case WM_COMMAND:
  145.           hMenu = GetMenu (hwnd) ;
  146.  
  147.           switch (LOWORD (wParam))
  148.           {
  149.           case IDM_FILE_OPEN:
  150.                     // Show the File Open dialog box
  151.  
  152.                if (!DibFileOpenDlg (hwnd, szFileName, szTitleName))
  153.                     return 0 ;
  154.                
  155.                     // If there's an existing DIB, free the memory
  156.  
  157.                if (pbmfh)
  158.                {
  159.                     free (pbmfh) ;
  160.                     pbmfh = NULL ;
  161.                }
  162.                     // Load the entire DIB into memory
  163.  
  164.                SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
  165.                ShowCursor (TRUE) ;
  166.  
  167.                pbmfh = DibLoadImage (szFileName) ;
  168.  
  169.                ShowCursor (FALSE) ;
  170.                SetCursor (LoadCursor (NULL, IDC_ARROW)) ;
  171.  
  172.                     // Invalidate the client area for later update
  173.  
  174.                InvalidateRect (hwnd, NULL, TRUE) ;
  175.  
  176.                if (pbmfh == NULL)
  177.                {
  178.                     MessageBox (hwnd, TEXT ("Cannot load DIB file"), 
  179.                                 szAppName, MB_ICONEXCLAMATION | MB_OK) ;
  180.                     return 0 ;
  181.                }
  182.                     // Get pointers to the info structure & the bits
  183.  
  184.                pbmi  = (BITMAPINFO *) (pbmfh + 1) ;
  185.                pBits = (BYTE *) pbmfh + pbmfh->bfOffBits ;
  186.  
  187.                     // Get the DIB width and height
  188.  
  189.                if (pbmi->bmiHeader.biSize == sizeof (BITMAPCOREHEADER))
  190.                {
  191.                     cxDib = ((BITMAPCOREHEADER *) pbmi)->bcWidth ;
  192.                     cyDib = ((BITMAPCOREHEADER *) pbmi)->bcHeight ;
  193.                }
  194.                else
  195.                {
  196.                     cxDib =      pbmi->bmiHeader.biWidth ;
  197.                     cyDib = abs (pbmi->bmiHeader.biHeight) ;
  198.                }
  199.                return 0 ;
  200.  
  201.           case IDM_FILE_SAVE:
  202.                     // Show the File Save dialog box
  203.  
  204.                if (!DibFileSaveDlg (hwnd, szFileName, szTitleName))
  205.                     return 0 ;
  206.                
  207.                     // Save the DIB to a disk file
  208.  
  209.                SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
  210.                ShowCursor (TRUE) ;
  211.  
  212.                bSuccess = DibSaveImage (szFileName, pbmfh) ;
  213.  
  214.                ShowCursor (FALSE) ;
  215.                SetCursor (LoadCursor (NULL, IDC_ARROW)) ;
  216.  
  217.                if (!bSuccess)
  218.                     MessageBox (hwnd, TEXT ("Cannot save DIB file"), 
  219.                                 szAppName, MB_ICONEXCLAMATION | MB_OK) ;
  220.                return 0 ;
  221.  
  222.           case IDM_FILE_PRINT:
  223.                if (!pbmfh)
  224.                     return 0 ;
  225.  
  226.                     // Get printer DC
  227.  
  228.               printdlg.Flags = PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION ;
  229.  
  230.               if (!PrintDlg (&printdlg))
  231.                     return 0 ;
  232.  
  233.                if (NULL == (hdcPrn = printdlg.hDC))
  234.                {
  235.                     MessageBox (hwnd, TEXT ("Cannot obtain Printer DC"),
  236.                                 szAppName, MB_ICONEXCLAMATION | MB_OK) ;
  237.                     return 0 ;
  238.                }
  239.                     // Check if the printer can print bitmaps
  240.  
  241.                if (!(RC_BITBLT & GetDeviceCaps (hdcPrn, RASTERCAPS)))
  242.                {
  243.                     DeleteDC (hdcPrn) ;
  244.                     MessageBox (hwnd, TEXT ("Printer cannot print bitmaps"),
  245.                                 szAppName, MB_ICONEXCLAMATION | MB_OK) ;
  246.                     return 0 ;
  247.                }
  248.                     // Get size of printable area of page
  249.  
  250.                cxPage = GetDeviceCaps (hdcPrn, HORZRES) ;
  251.                cyPage = GetDeviceCaps (hdcPrn, VERTRES) ;
  252.  
  253.                bSuccess = FALSE ;
  254.  
  255.                     // Send the DIB to the printer
  256.  
  257.                SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
  258.                ShowCursor (TRUE) ;
  259.  
  260.                if ((StartDoc (hdcPrn, &di) > 0) && (StartPage (hdcPrn) > 0))
  261.                {
  262.                     ShowDib (hdcPrn, pbmi, pBits, cxDib, cyDib,
  263.                              cxPage, cyPage, wShow) ;
  264.                     
  265.                     if (EndPage (hdcPrn) > 0)
  266.                     {
  267.                          bSuccess = TRUE ;
  268.                          EndDoc (hdcPrn) ;
  269.                     }
  270.                }
  271.                ShowCursor (FALSE) ;
  272.                SetCursor (LoadCursor (NULL, IDC_ARROW)) ;
  273.  
  274.                DeleteDC (hdcPrn) ;
  275.  
  276.                if (!bSuccess)
  277.                     MessageBox (hwnd, TEXT ("Could not print bitmap"),
  278.                                 szAppName, MB_ICONEXCLAMATION | MB_OK) ;
  279.                return 0 ;
  280.  
  281.           case IDM_EDIT_COPY:
  282.           case IDM_EDIT_CUT:
  283.                if (!pbmfh)
  284.                     return 0 ;
  285.  
  286.                     // Make a copy of the packed DIB
  287.  
  288.                hGlobal = GlobalAlloc (GHND | GMEM_SHARE, pbmfh->bfSize -
  289.                                         sizeof (BITMAPFILEHEADER)) ;
  290.  
  291.                pGlobal = GlobalLock (hGlobal) ;
  292.  
  293.                CopyMemory (pGlobal, (BYTE *) pbmfh + sizeof (BITMAPFILEHEADER),
  294.                            pbmfh->bfSize - sizeof (BITMAPFILEHEADER)) ;
  295.  
  296.                GlobalUnlock (hGlobal) ;
  297.  
  298.                     // Transfer it to the clipboard
  299.  
  300.                OpenClipboard (hwnd) ;
  301.                EmptyClipboard () ;
  302.                SetClipboardData (CF_DIB, hGlobal) ;
  303.                CloseClipboard () ;
  304.  
  305.                if (LOWORD (wParam) == IDM_EDIT_COPY)
  306.                     return 0 ;
  307.                                         // fall through if IDM_EDIT_CUT 
  308.           case IDM_EDIT_DELETE:
  309.                if (pbmfh)
  310.                {
  311.                     free (pbmfh) ;
  312.                     pbmfh = NULL ;
  313.                     InvalidateRect (hwnd, NULL, TRUE) ;
  314.                }
  315.                return 0 ;
  316.  
  317.           case IDM_SHOW_NORMAL:
  318.           case IDM_SHOW_CENTER:
  319.           case IDM_SHOW_STRETCH:
  320.           case IDM_SHOW_ISOSTRETCH:
  321.                CheckMenuItem (hMenu, wShow, MF_UNCHECKED) ;
  322.                wShow = LOWORD (wParam) ;
  323.                CheckMenuItem (hMenu, wShow, MF_CHECKED) ;
  324.                InvalidateRect (hwnd, NULL, TRUE) ;
  325.                return 0 ;
  326.           }
  327.           break ;
  328.          
  329.      case WM_PAINT:
  330.           hdc = BeginPaint (hwnd, &ps) ;
  331.  
  332.           if (pbmfh)
  333.                ShowDib (hdc, pbmi, pBits, cxDib, cyDib, 
  334.                         cxClient, cyClient, wShow) ;
  335.  
  336.           EndPaint (hwnd, &ps) ;
  337.           return 0 ;
  338.           
  339.      case WM_DESTROY:
  340.           if (pbmfh)
  341.                free (pbmfh) ;
  342.  
  343.           PostQuitMessage (0) ;
  344.           return 0 ;
  345.      }
  346.      return DefWindowProc (hwnd, message, wParam, lParam) ;
  347. }